﻿#include <QDateTime>
#include <QColor>
#include "assist_cross.h"

AssistCross::AssistCross(QCustomPlot *plot, QString target_layer, QCPLayerable *parent_layerable)
    : QCPLayerable(plot, target_layer, parent_layerable)
    , real_time_flag_(false)
    , able_(true)
	, plot_(plot)
{
    assist_cross_tip_widget_.setParent(qobject_cast<QWidget*>(plot->parent()));
	vertical_line_ = new QCPItemStraightLine(plot_);
	vertical_line_->setSelectable(false);
	vertical_line_->point1->setCoords(0, 200);
	vertical_line_->point2->setCoords(1, 200);
	vertical_line_->setLayer(QStringLiteral("assist_cross"));
	horizontal_line_ = new QCPItemStraightLine(plot_);
	horizontal_line_->setSelectable(false);
	horizontal_line_->point1->setCoords(1000, 0);
	horizontal_line_->point2->setCoords(1000, 1);
	horizontal_line_->setLayer(QStringLiteral("assist_cross"));

    connect(parentPlot(), &QCustomPlot::mouseMove, this, &AssistCross::MouseMoveHandle);
}

AssistCross::~AssistCross()
{

}

void AssistCross::SetTracer(QCPGraph *graph, std::string id)
{
    QCPItemTracer *item_tracer = new QCPItemTracer(parentPlot());
    item_tracer->setLayer(QStringLiteral("assist_cross"));
    item_tracer->setGraph(graph);
    //item_tracer->setGraphKey(5.5);
    item_tracer->setInterpolating(false);
    item_tracer->setStyle(QCPItemTracer::tsNone);
    item_tracer->setPen(graph->pen());
    item_tracer->setBrush(graph->brush());
    item_tracer->setSize(7);
    item_tracer->setSelectable(false);

//     std::map<std::string, QCPItemTracer*>::iterator it = tracer_map_.find(id);
//     if (it == tracer_map_.end())
//     {
//         tracer_map_[id] = item_tracer;
// 	}
	
	bool found = false;
	foreach(auto& tracer_pair, tracer_list_)
	{
		if (tracer_pair.first == id)
		{
			found = true;
			break;
		}
	}
	if (!found)
	{
		tracer_list_.append(QPair<std::string, QCPItemTracer*>(id, item_tracer));
	}
}

void AssistCross::RemoveTracer(std::string id)
{
//     std::map<std::string, QCPItemTracer*>::iterator it = tracer_map_.find(id);
//     if (it != tracer_map_.end())
//     {
//         QCPItemTracer* tracer = it->second;
//         parentPlot()->removeItem(tracer);
//         tracer_map_.erase(id);
// 	}
	foreach(auto& tracer_pair, tracer_list_)
	{
		if (tracer_pair.first == id)
		{
			parentPlot()->removeItem(tracer_pair.second);
			tracer_list_.removeOne(tracer_pair);
			break;
		}
	}
}

void AssistCross::ChangeAssistTracerRealTime(std::string id, QCPGraph *graph)
{
//     std::map<std::string, QCPItemTracer*>::iterator it = tracer_map_.find(id);
//     if (it != tracer_map_.end())
//     {
//         it->second->setGraph(graph);
// 	}
	foreach(auto& tracer_pair, tracer_list_)
	{
		if (tracer_pair.first == id)
		{
			tracer_pair.second->setGraph(graph);
			break;
		}
	}
}

void AssistCross::Enable(bool able)
{
    able_ = able;
    if (able)
    {
        assist_cross_tip_widget_.show();
    }
    else
    {
        assist_cross_tip_widget_.hide();
    }
    vertical_line_->setVisible(able);
    horizontal_line_->setVisible(able);
    //layer()->replot();
}

void AssistCross::SetAssistColor(const QString& line_color, const QString& bg_color)
{
	_kPlotAssistLineColor = QColor(line_color.toUInt(NULL, 16));
    _kPlotAssistBackgroundColor = QColor(bg_color.toUInt(NULL, 16));

    QPen line_pen;
	line_pen.setColor(_kPlotAssistLineColor);
	line_pen.setWidth(2);
	vertical_line_->setPen(line_pen);
	horizontal_line_->setPen(line_pen);
}

void AssistCross::SetCurrentState(bool real_time_flag, double current_point)
{
    real_time_flag_ = real_time_flag;
    if (real_time_flag_)
    {
		foreach(auto& tracer_pair, tracer_list_)
		{
			tracer_pair.second->setGraphKey(current_point);
		}
        layer()->replot();
    }
}

void AssistCross::SetCurrentTracer(double current_point)
{
	foreach(auto& tracer_pair, tracer_list_)
	{
		tracer_pair.second->setGraphKey(current_point);
	}
	//设置垂直辅助线位置
	//判断是否越界
	vertical_line_->point1->setCoords(current_point, 0);
	vertical_line_->point2->setCoords(current_point, 1);
    layer()->replot();
}

void AssistCross::SetAssistTipWidgetPos(int x, int y)
{
    mouse_x_ = x;
    mouse_y_ = y;
}

void AssistCross::SetAssistTipVisible(bool visible)
{
    assist_cross_tip_widget_.setVisible(visible && able_);
}

void AssistCross::HideAssistTipWidget()
{
    assist_cross_tip_widget_.setVisible(false);
}

void AssistCross::MouseMoveHandle(QMouseEvent *event)
{
    //跟随鼠标移动
    this->SetAssistTipWidgetPos(event->pos().x(), event->pos().y());
    if (!real_time_flag_)
    {
        double x = parentPlot()->xAxis->pixelToCoord(event->pos().x());
        double y = parentPlot()->yAxis->pixelToCoord(event->pos().y());

        //设置水平辅助线的位置
        horizontal_line_->point1->setCoords(0, y);
        horizontal_line_->point2->setCoords(1, y);

        if (!tracer_list_.empty())
        {
			foreach(auto& tracer_pair, tracer_list_)
			{
				tracer_pair.second->setGraphKey(x);
            }
            //设置垂直辅助线的位置
			QList<QCPItemPosition *> postions = tracer_list_.begin()->second->positions();
            if (postions.size() > 0)
            {
                vertical_line_->point1->setCoords(postions[0]->key(), 0);
                vertical_line_->point2->setCoords(postions[0]->key(), 1);
            }
            layer()->replot();
        }
    }
}

void AssistCross::draw(QCPPainter * painter)
{
    painter->setFont(QFont("黑体", 8));
    QPen pen;
    pen.setWidth(2);
	pen.setColor(QColor(Qt::red));
    painter->setPen(pen);
    painter->setRenderHint(QPainter::SmoothPixmapTransform);

    QFontMetrics font_metrics = painter->fontMetrics();

    if (!tracer_list_.empty())
    {
        /*
        0、先获取到时间信息，只需要获取一次
        1、获取到曲线名字，
        2、获取到曲线颜色
        3、画一个背景
        4、先画时间，再画图+ 值
        */
        QPixmap pixmap(500, 500);
        pixmap.fill(_kPlotAssistBackgroundColor);
        QPainter pixmap_painter;

        int row_redge = painter->fontMetrics().height();             //设置字体像素高度
        bool time_is_draw = true;      //控制时间 只画一次
        int row_count = 0;             //记录画了几行数据，计算大小
        int max_length = 0;           //记录所画字符串最大长度

        pixmap_painter.begin(&pixmap);
        pixmap_painter.setPen(Qt::white);
        pixmap_painter.setRenderHint(QPainter::SmoothPixmapTransform);
        for (auto iter = tracer_list_.begin(); iter != tracer_list_.end(); ++iter)
        {
            int pixmap_row_redge = row_redge + 7;
			QList<QCPItemPosition *> postions = iter->second->positions();
            if (postions.size() > 0)
            {
                if (time_is_draw)
                {
                    //画时间,只画一次
                    QPen pen;
                    pen.setColor(Qt::white);
                    pen.setWidth(2);
                    pixmap_painter.setPen(pen);
                    QString str = QString("(%1)").arg(postions[0]->key(), 0, 'f', 3);
					pixmap_painter.drawText(5, 15, str);
                    time_is_draw = false;
                    row_count++;
                }
                //画线
				QPen pen = iter->second->pen();
                pen.setWidth(3);
                pixmap_painter.setPen(pen);
                pixmap_painter.drawLine(5, 10 + pixmap_row_redge * row_count, 15, 10 + pixmap_row_redge * row_count);

                //画名字，画值
				QString graph_name = iter->second->graph()->name();
                QString value_str = QString("(%1)").arg(/*static_cast<int>*/(postions[0]->value()));
				pixmap_painter.setPen(iter->second->pen());
                pixmap_painter.drawText(20, 15 + pixmap_row_redge  * row_count, graph_name + " " + value_str);
                row_count++;

                int length = font_metrics.width(graph_name + " " + value_str);
                if (length > max_length)
                {
                    max_length = length;
                }

                //移动鼠标位置 mouse_x_、 mouse_y_是鼠标在单个图中的位置
				//转换为全局位置
				QWidget* main_widget = qobject_cast<QWidget*>(assist_cross_tip_widget_.parent());
                QPoint global_mouse_pos = plot_->mapTo(qobject_cast<QWidget*>(main_widget), QPoint(mouse_x_, mouse_y_));

                assist_cross_tip_widget_.setFixedSize(max_length + 80, row_count * pixmap_row_redge + 10);
				//左下角
				if (main_widget->pos().x()+ global_mouse_pos.x() > main_widget->pos().x() + assist_cross_tip_widget_.width() + 10 &&
					global_mouse_pos.y() < main_widget->pos().y() + main_widget->height() - assist_cross_tip_widget_.height() - 10)
				{
					assist_cross_tip_widget_.move(global_mouse_pos.x() - assist_cross_tip_widget_.width() - 10, global_mouse_pos.y() + 10);
				}
				//右下角
				else if (main_widget->pos().x() + global_mouse_pos.x() < main_widget->pos().x() + main_widget->width() - assist_cross_tip_widget_.width() - 10 &&
					global_mouse_pos.y() < main_widget->pos().y() + main_widget->height() - assist_cross_tip_widget_.height() - 10)
				{
					assist_cross_tip_widget_.move(global_mouse_pos.x() + 10, global_mouse_pos.y() + 10);
				}
				//左上角
				else if (main_widget->pos().x() + global_mouse_pos.x() > main_widget->pos().x() + assist_cross_tip_widget_.width() + 10 &&
					global_mouse_pos.y() > main_widget->pos().y() + assist_cross_tip_widget_.height() + 10)
				{
					assist_cross_tip_widget_.move(global_mouse_pos.x() - 10, global_mouse_pos.y() - 10);
				}
				//右上角
				else if (main_widget->pos().x() + global_mouse_pos.x() < main_widget->pos().x() + main_widget->width() - assist_cross_tip_widget_.width() - 10 &&
					global_mouse_pos.y() > main_widget->pos().y() - assist_cross_tip_widget_.height() + 10)
				{
					assist_cross_tip_widget_.move(global_mouse_pos.x() + 10, global_mouse_pos.y() - 10);
				}
				else
				{

                }
            }
        }
        pixmap_painter.end();
        assist_cross_tip_widget_.SetPixmap(pixmap);
    }
}
